#include "import_map_service.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <chrono>
#include <thread>
#include <nlohmann/json.hpp>

// 添加UTF-8支持
#if defined(_MSC_VER) && defined(_WIN32)
#pragma execution_character_set("utf-8")
#endif

using json = nlohmann::json;

// 全局CURL初始化和清理
class CurlGlobalManager {
public:
    CurlGlobalManager() {
        curl_global_init(CURL_GLOBAL_ALL);
        std::cout << "CURL initialization complete" << std::endl;
    }
    
    ~CurlGlobalManager() {
        curl_global_cleanup();
        std::cout << "CURL cleanup complete" << std::endl;
    }
};

// 创建全局单例对象确保CURL在程序开始时初始化，结束时清理
static CurlGlobalManager curlManager;

// CURL响应回调函数
size_t ImportMapService::WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

// 获取POI数据（兴趣点数据）
std::string ImportMapService::getPoiData(const std::string& query, int pageNum) {
    // 构建API请求URL
    std::stringstream url;
    url << "https://api.map.baidu.com/place/v2/search?query=" << query;
    url << "&region=Beijing";
    url << "&output=json";
    url << "&page_size=20";
    url << "&page_num=" << pageNum;
    url << "&ak=" << ak;
    
    // 使用CURL发送请求
    CURL* curl = curl_easy_init();
    std::string response;
    
    if (curl) {
        char* encodedQuery = curl_easy_escape(curl, query.c_str(), query.length());
        if (encodedQuery) {
            // 更新URL使用编码后的查询词
            url.str("");
            url << "https://api.map.baidu.com/place/v2/search?query=" << encodedQuery;
            url << "&region=Beijing";
            url << "&output=json";
            url << "&page_size=20";
            url << "&page_num=" << pageNum;
            url << "&ak=" << ak;
            curl_free(encodedQuery);
        }
        
        curl_easy_setopt(curl, CURLOPT_URL, url.str().c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
        
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
            return "{}";
        }
        
        curl_easy_cleanup(curl);
    }
    
    return response;
}

// 获取地点轮廓数据
std::string ImportMapService::getPlaceOutline(const std::string& placeName) {
    // 构建API请求URL
    std::stringstream url;
    url << "https://api.map.baidu.com/api_region_search/v1/search?keyword=" << placeName;
    url << "&sub_admin=0";
    url << "&extensions=3";  // 返回轮廓数据
    url << "&output=json";
    url << "&ak=" << ak;
    
    // 使用CURL发送请求
    CURL* curl = curl_easy_init();
    std::string response;
    
    if (curl) {
        char* encodedName = curl_easy_escape(curl, placeName.c_str(), placeName.length());
        if (encodedName) {
            // 更新URL使用编码后的地点名称
            url.str("");
            url << "https://api.map.baidu.com/api_region_search/v1/search?keyword=" << encodedName;
            url << "&sub_admin=0";
            url << "&extensions=3";
            url << "&output=json";
            url << "&ak=" << ak;
            curl_free(encodedName);
        }
        
        curl_easy_setopt(curl, CURLOPT_URL, url.str().c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
        
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
            return "{}";
        }
        
        curl_easy_cleanup(curl);
    }
    
    return response;
}

// 从CSV文件导入基础地点数据
bool ImportMapService::importPlacesFromCSV(PlaceDB& placeDb, const std::string& csvFilePath) {
    std::ifstream file(csvFilePath);
    if (!file.is_open()) {
        std::cerr << "Cannot open CSV file: " << csvFilePath << std::endl;
        return false;
    }
    
    std::string line;
    // 跳过标题行
    std::getline(file, line);
    
    std::vector<Place> places;
    
    // 逐行读取并解析
    while (std::getline(file, line)) {
        std::stringstream ss(line);
        std::string field;
        Place place;
        
        // 格式：名称,类型,纬度,经度,描述,地址
        // 解析名称
        if (!std::getline(ss, field, ',')) break;
        place.name = field;
        
        // 解析类型
        if (!std::getline(ss, field, ',')) break;
        place.type = field;
        
        // 解析纬度
        if (!std::getline(ss, field, ',')) break;
        try {
            place.latitude = std::stod(field);
        } catch (...) {
            place.latitude = 0.0;
        }
        
        // 解析经度
        if (!std::getline(ss, field, ',')) break;
        try {
            place.longitude = std::stod(field);
        } catch (...) {
            place.longitude = 0.0;
        }
        
        // 解析描述 (可能包含逗号，所以需要特殊处理)
        if (!std::getline(ss, field, ',')) break;
        place.description = field;
        
        // 解析地址 (剩余部分)
        std::string address;
        while (std::getline(ss, field, ',')) {
            if (!address.empty()) address += ",";
            address += field;
        }
        place.address = address;
        
        // 轮廓数据初始为空，后续通过API获取
        place.outline = "";
        
        places.push_back(place);
    }
    
    file.close();
    
    // 批量添加到数据库
    return placeDb.addPlacesBatch(places);
}

// 创建基础地点CSV文件模板
bool ImportMapService::createBasicPlacesCSVTemplate(const std::string& csvFilePath) {
    std::ofstream file(csvFilePath);
    if (!file.is_open()) {
        std::cerr << "Cannot create CSV file: " << csvFilePath << std::endl;
        return false;
    }
    
    // 写入标题行
    file << "Name,Type,Latitude,Longitude,Description,Address\n";
    
    // 写入一些北京的热门地点示例
    file << "Forbidden City,Attraction,39.916345,116.397155,Imperial Palace of Ming and Qing Dynasties,4 Jingshan Front St, Dongcheng District, Beijing\n";
    file << "Peking University,School,39.992084,116.310317,One of China's most prestigious universities,5 Yiheyuan Rd, Haidian District, Beijing\n";
    file << "Tsinghua University,School,40.002897,116.326701,One of China's most prestigious universities,30 Shuangqing Rd, Haidian District, Beijing\n";
    file << "Tiananmen Square,Attraction,39.903524,116.397096,One of the largest city squares in the world,Dongcheng District, Beijing\n";
    file << "National Library of China,Library,39.942350,116.330559,North Branch of National Library,33 Zhongguancun S Ave, Haidian District, Beijing\n";
    file << "Beijing Railway Station,Transportation,39.902863,116.427312,One of Beijing's main railway hubs,Beijing Railway Station, Dongcheng District, Beijing\n";
    file << "Wangfujing Street,Shopping,39.916527,116.407845,Famous shopping street in Beijing,Dongcheng District, Beijing\n";
    file << "Beijing West Railway Station,Transportation,39.894485,116.322104,One of Beijing's main railway stations,Lianhuachi East Rd, Fengtai District, Beijing\n";
    file << "Beijing Capital International Airport,Transportation,40.080699,116.603739,One of China's largest airports,Shunyi District, Beijing\n";
    file << "Summer Palace,Attraction,39.999507,116.275729,Famous imperial garden in China,19 Xinjiangongmen Rd, Haidian District, Beijing\n";
    
    file.close();
    return true;
}

// 混合导入方案：离线数据+API补充
bool ImportMapService::importPlacesMixedMethod(PlaceDB& placeDb, const std::string& csvFilePath, 
                               const std::vector<std::string>& placeTypes, 
                               int maxPagesPerType) {
    // 1. 先从CSV文件导入基础数据
    std::cout << "Importing basic place data from CSV..." << std::endl;
    if (!importPlacesFromCSV(placeDb, csvFilePath)) {
        std::cerr << "Failed to import basic data from CSV!" << std::endl;
        return false;
    }
    std::cout << "Basic data import complete!" << std::endl;
    
    // 2. 使用API获取更多地点数据
    std::cout << "Importing more place data using API..." << std::endl;
    int totalImported = 0;
    
    for (const auto& type : placeTypes) {
        std::cout << "Getting places of type: " << type << "..." << std::endl;
        
        for (int page = 0; page < maxPagesPerType; page++) {
            std::cout << "  Processing page: " << page << std::endl;
            
            // 通过API获取地点
            std::string query = type + " Beijing";
            std::string response = getPoiData(query, page);
            
            // 解析JSON响应
            try {
                json jsonResponse = json::parse(response);
                
                if (jsonResponse.contains("status") && jsonResponse["status"].get<int>() != 0) {
                    if (jsonResponse.contains("message")) {
                        std::cerr << "API returned error: " << jsonResponse["message"].get<std::string>() << std::endl;
                    } else {
                        std::cerr << "API returned unknown error" << std::endl;
                    }
                    break;
                }
                
                if (!jsonResponse.contains("results") || jsonResponse["results"].size() == 0) {
                    std::cout << "  No more data" << std::endl;
                    break;
                }
                
                auto& results = jsonResponse["results"];
                
                // 处理返回的地点数据
                std::vector<Place> newPlaces;
                for (auto& result : results) {
                    Place place;
                    if (result.contains("name")) {
                        place.name = result["name"].get<std::string>();
                    } else {
                        continue; // 跳过没有名称的地点
                    }
                    
                    place.type = type;
                    
                    // 判断是否有location字段
                    if (result.contains("location")) {
                        if (result["location"].contains("lat") && result["location"].contains("lng")) {
                            place.latitude = result["location"]["lat"].get<double>();
                            place.longitude = result["location"]["lng"].get<double>();
                        } else {
                            continue; // 跳过没有完整位置的地点
                        }
                    } else {
                        continue; // 跳过没有位置的地点
                    }
                    
                    // 判断是否有address字段
                    if (result.contains("address")) {
                        place.address = result["address"].get<std::string>();
                    } else {
                        place.address = "Beijing";
                    }
                    
                    // 判断是否有detail_info字段
                    if (result.contains("detail_info") && result["detail_info"].contains("tag")) {
                        place.description = result["detail_info"]["tag"].get<std::string>();
                    } else {
                        place.description = type + " type place";
                    }
                    
                    place.outline = ""; // 轮廓数据初始为空
                    
                    newPlaces.push_back(place);
                }
                
                // 批量添加到数据库
                if (!newPlaces.empty()) {
                    if (placeDb.addPlacesBatch(newPlaces)) {
                        totalImported += newPlaces.size();
                        std::cout << "  Successfully imported " << newPlaces.size() << " places" << std::endl;
                    }
                }
            } catch (const std::exception& e) {
                std::cerr << "Failed to parse JSON: " << e.what() << std::endl;
                std::cerr << "Response content: " << response << std::endl;
                continue;
            }
            
            // 避免API请求过于频繁
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
        }
    }
    
    std::cout << "API import complete! Total imported: " << totalImported << " places" << std::endl;
    
    // 3. 补充重要地点的轮廓数据
    std::cout << "Getting outline data for important places..." << std::endl;
    std::vector<Place> placesWithoutOutline = placeDb.getAllPlacesWithoutOutline();
    int outlineCount = 0;
    
    // 优先处理重要类型的地点
    std::vector<std::string> priorityTypes = {"Attraction", "School", "Park"};
    
    for (const auto& type : priorityTypes) {
        for (const auto& place : placesWithoutOutline) {
            if (place.type == type) {
                std::cout << "  Getting outline data for: " << place.name << "..." << std::endl;
                
                // 通过API获取轮廓数据
                std::string outlineData = getPlaceOutline(place.name);
                
                if (!outlineData.empty()) {
                    try {
                        json outlineJson = json::parse(outlineData);
                        if (outlineJson.contains("status") && outlineJson["status"].get<int>() == 0 && 
                            outlineJson.contains("results") && outlineJson["results"].size() > 0) {
                            // 更新地点轮廓
                            if (placeDb.updatePlaceOutline(place.id, outlineData)) {
                                outlineCount++;
                                std::cout << "  Outline data update successful!" << std::endl;
                            }
                        }
                    } catch (const std::exception& e) {
                        std::cerr << "Failed to parse outline JSON: " << e.what() << std::endl;
                        continue;
                    }
                }
                
                // 避免API请求过于频繁
                std::this_thread::sleep_for(std::chrono::milliseconds(500));
                
                // 限制请求数量，避免超过API限制
                if (outlineCount >= 50) {
                    std::cout << "Reached outline request limit, stopping further outline data retrieval" << std::endl;
                    break;
                }
            }
        }
        
        if (outlineCount >= 50) {
            break;
        }
    }
    
    std::cout << "Outline data import complete! Updated " << outlineCount << " places with outline data" << std::endl;
    std::cout << "Mixed place data import complete!" << std::endl;
    
    return true;
} 